package cn.maydaymemory.mastery.shop;

import cn.maydaymemory.mastery.PluginMastery;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import java.io.File;
import java.util.*;


public class SellInventory {
    private Inventory inventory;
    private HumanEntity player;
    private Map<ItemStack,ItemStack> mapping = new HashMap<>();
    private static Map<String,SellInventory> sellInventoryMap = new HashMap<>();
    private static List<String> viewer = new ArrayList<>();

    public SellInventory(HumanEntity player){
        this.player = player;
        sellInventoryMap.put(player.getName(),this);
    }

    public static SellInventory getInstance(String playername){
        return sellInventoryMap.get(playername);
    }

    public static boolean isViewer(String playername){
        return viewer.contains(playername);
    }

    public static void stopView(String playername){
        viewer.remove(playername);
    }

    public void openView(){
        File fileConfig = new File(PluginMastery.getInstance().getDataFolder(),"config.yml");
        FileConfiguration config = PluginMastery.getInstance().getConfigManager().getConfig(fileConfig);
        String title = PluginMastery.getInstance().getCurrent_lang().getString("sell_view_title")+"";
        title = title.replaceAll("%price%",PluginMastery.getInstance().getCurrent_lang().getString("non-value")+"");
        inventory = Bukkit.createInventory(null, config.getInt("sell_view_size",4)*9,title);
        player.closeInventory();
        viewer.add(player.getName());
        player.openInventory(inventory);
    }

    public List<Shop.Price> getPrice(){
        List<Shop.Price> list = new ArrayList<>();
        for(ItemStack itemStack:inventory.getContents()){
            if(itemStack==null) continue;
            ItemStack good = getMapping(itemStack);
            if(good == null) continue;
            if(Shop.getPrice(good)!=null) list.add(Shop.getPrice(good));
        }
        return list;
    }

    private static class PriceCamp implements Comparator<Shop.Price>{
        @Override
        public int compare(Shop.Price o1, Shop.Price o2) {
            Shop.Currency c1 = Shop.getCurrency(o1.getType());
            Shop.Currency c2 = Shop.getCurrency(o2.getType());
            if(c1 == null||c2 == null) return 0;
            return c1.getRank()-c2.getRank();
        }
    }

    public List<Shop.Price> getResultPrice(){
        File fileConfig = new File(PluginMastery.getInstance().getDataFolder(),"config.yml");
        FileConfiguration config = PluginMastery.getInstance().getConfigManager().getConfig(fileConfig);
        List<Shop.Price> prices = getPrice();
        List<Shop.Price> results = new ArrayList<>();
        for(Shop.Price price:prices)
            addPriceToResult(results,price);

        int exchange = config.getInt("exchange",64);
        ArrayList<String> sequence = Shop.getCurrencySequence();
        for(int f=0;f<results.size();f++){
            Shop.Price price = results.get(f);
            Shop.Currency currency = Shop.getCurrency(price.getType());
            if(currency == null) continue;
            for(int f2 = 0; f2<sequence.indexOf(price.getType()) ; f2++){
                double alpha = Math.pow(exchange,Shop.getCurrency(sequence.get(f2)).getRank()-currency.getRank());
                int answer = (int) (price.getPrice()/alpha);
                if(answer>=1){
                    price.price = price.price%(int)alpha;
                    addPriceToResult(results,new Shop.Price(sequence.get(f2),answer));
                    break;
                }
            }
        }
        List<Shop.Price> zombiePrice = new ArrayList<>();
        for(Shop.Price price:results){
            if(price.getPrice()==0) zombiePrice.add(price);
        }
        results.removeAll(zombiePrice);
        return results;
    }

    private void addPriceToResult(List<Shop.Price> results,Shop.Price price){
        if(price.getPrice()==0) return;
        boolean b =false;
        for(Shop.Price result: results){
            if(result.getType().equals(price.getType())){
                result.price+=price.getPrice();
                b=true;
                break;
            }
        }
        if(!b) results.add(price);
        results.sort(new PriceCamp());
    }

    public void refreshLore(ItemStack item,ItemStack init){
        ItemMeta meta=item.getItemMeta();
        if(meta==null) return;
        List<String> lore = meta.getLore();
        if(lore == null) lore = new ArrayList<>();
        for(String str : lore){
            if(str.contains("§d§e§f")) lore.remove(str);
        }
        if(init == null) return;
        Shop.Price price = Shop.getPrice(init);
        Economy econ = PluginMastery.getInstance().getEcon();
        if( price==null || (price.getType().equalsIgnoreCase("vault")&&econ == null) ){
            lore.add("§d§e§f"+PluginMastery.getInstance().getCurrent_lang().getString("non-value"));
            meta.setLore(lore);
            item.setItemMeta(meta);
            return;
        }
        List<String> add = PluginMastery.getInstance().getCurrent_lang().getStringList("lore");
        for(String str : add){
            if (price.getType().equalsIgnoreCase("vault"))
                lore.add("§d§e§f"+str.replaceAll("%price%",price.getPrice()+"").replaceAll("%type%",econ.currencyNamePlural()));
            else
                lore.add("§d§e§f"+str.replaceAll("%price%",price.getPrice()+"").replaceAll("%type%",price.getType()));
        }
        meta.setLore(lore);
        item.setItemMeta(meta);
    }

    public void addItem(int index){
        ItemStack item = player.getInventory().getItem(index);
        if(item==null||item.getType().equals(Material.AIR)) return;
        int slot = inventory.firstEmpty();
        if(slot<0) return;
        ItemStack key = item.clone();
        refreshLore(key,item);
        mapping.put(key,item);
        inventory.setItem(slot,key);
        player.getInventory().setItem(index,new ItemStack(Material.AIR));
        refreshInventory();
    }


    private ItemStack getMapping(ItemStack item){
        for(ItemStack k : mapping.keySet()){
            if(k.equals(item)) return mapping.get(k);
        }
        return null;
    }

    public void removeItem(int index){
        ItemStack item = inventory.getItem(index);
        if(item==null||item.getType().equals(Material.AIR)) return;
        ItemStack init = getMapping(item);
        if(init==null||init.getType().equals(Material.AIR)) return;
        if(player.getInventory().firstEmpty()>=0) {
            inventory.setItem(index, new ItemStack(Material.AIR));
        /*
        Map<Integer,ItemStack> uger = player.getInventory().addItem(init);
        for(Integer f : uger.keySet()){
            item.setAmount(uger.get(f).getAmount());
            ItemStack r = init.clone();
            r.setAmount(item.getAmount());
            refreshLore(item,r);
            mapping.put(item,r);
            inventory.setItem(index,item);
        }*/
            player.getInventory().setItem(player.getInventory().firstEmpty(), init);
            refreshInventory();
        }
    }

    public void refreshInventory(){
        File fileConfig = new File(PluginMastery.getInstance().getDataFolder(),"config.yml");
        FileConfiguration config = PluginMastery.getInstance().getConfigManager().getConfig(fileConfig);
        ItemStack[] itemStacks = inventory.getContents();
        List<Shop.Price> results = getResultPrice();
        String title = PluginMastery.getInstance().getCurrent_lang().getString("sell_view_title")+"";
        StringBuilder pricebuilder =new StringBuilder();
        Economy econ = PluginMastery.getInstance().getEcon();
        boolean b = true;
        for(Shop.Price result: results) {
            if(result.getType().equalsIgnoreCase("vault")&&econ == null) continue;
            b=false;
            if(result.getType().equalsIgnoreCase("vault"))
                pricebuilder.append("§0").append(result.getPrice()).append("§l").append(econ.currencyNamePlural()).append(" ");
            else
                pricebuilder.append("§0").append(result.getPrice()).append("§l").append(result.getType()).append(" ");
        }
        if(results.isEmpty()||b) pricebuilder.append(PluginMastery.getInstance().getCurrent_lang().getString("non-value"));
        title = title.replaceAll("%price%",pricebuilder.toString());
        inventory = Bukkit.createInventory(null,config.getInt("sell_view_size",4)*9,title);
        inventory.setContents(itemStacks);
        viewer.add(player.getName());
        player.closeInventory();
        player.openInventory(inventory);
    }

    public void settle(){
        List<Shop.Price> results = getResultPrice();
        for(Shop.Price result : results){
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(),"MasteryAdmin currencygive "+player.getName()+" "+result.getPrice()+" "+result.getType());
        }
    }
}
